package cn.bearspark.framework.web.starter.handler;

import cn.bearspark.framework.web.starter.exception.RequestLimitException;
import cn.bearspark.framework.web.starter.vo.ResponseVO;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.validation.ConstraintViolationException;
import org.apache.catalina.connector.ClientAbortException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.method.annotation.MethodArgumentTypeMismatchException;

import java.io.IOException;

/**
 * 全局异常处理器
 *
 * @author f
 */
@RestControllerAdvice
public class GlobalExceptionHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    /**
     * 处理 Exception 异常
     *
     * @param request 请求对象
     * @param e       异常
     * @return 返回异常的视图对象
     */
    @ExceptionHandler(Exception.class)
    public ResponseVO<Object> errorHandler(HttpServletRequest request, Exception e) {
        LOGGER.error("{}, error is {}", request.getRequestURL(), e.getMessage(), e);
        return ResponseVO.fail();
    }

    /**
     * 处理限流异常
     *
     * @param e 异常
     * @return 返回异常的视图对象
     */
    @ExceptionHandler(RequestLimitException.class)
    public ResponseVO<Object> requestLimitExceptionHandler(RequestLimitException e) {
        return ResponseVO.badRequest(e.getMessage());
    }

    /**
     * 处理方法参数不匹配异常
     *
     * @param e 异常
     * @return 返回异常的视图对象
     */
    @ExceptionHandler(MethodArgumentTypeMismatchException.class)
    public ResponseVO<Object> methodArgumentTypeMismatchExceptionHandler(MethodArgumentTypeMismatchException e) {
        return ResponseVO.badRequest(e.getMessage());
    }

    /**
     * 处理参数校验异常
     *
     * @param e 异常
     * @return 返回异常的视图对象
     */
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseVO<Object> validationExceptionHandler(MethodArgumentNotValidException e) {
        FieldError fieldError = e.getFieldError();
        return ResponseVO.badRequest(fieldError.getField() + fieldError.getDefaultMessage());
    }

    /**
     * 处理自定义参数校验异常
     *
     * @param e 异常
     * @return 返回异常的视图对象
     */
    @ExceptionHandler(ConstraintViolationException.class)
    public ResponseVO<Object> customValidationExceptionHandler(ConstraintViolationException e) {
        return ResponseVO.badRequest(e.getConstraintViolations().iterator().next().getMessage());
    }

    /**
     * 处理前端播放器断开异常
     *
     * @param request 请求对象
     * @param e       异常
     * @return 返回异常的视图对象
     */
    @ExceptionHandler(IOException.class)
    public ResponseVO<Object> clientAbortExceptionHandler(HttpServletRequest request, IOException e) {
        if (e.getMessage().equals("Broken pipe")) {
            return ResponseVO.badRequest(e.getMessage());
        } else {
            return errorHandler(request, e);
        }
    }

}
